package trss.model;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;


import trss.bencode.BDecoder;
import trss.bencode.BDictionary;
import trss.bencode.BElement;
import trss.bencode.BFormatException;
import trss.model.torrent.MetaFile;
import trss.util.Utils;

@Entity
@Table(name = "torrent")
public class Torrent {
    User owner;
    MetaFile meta;
    byte[] origData;
    String fileName;
    int fileSize = 0;
    
    private Long id;
    
    public Torrent () {}
    
    public Torrent(String fileName, InputStream is) throws IOException, BFormatException {
        this.fileName = fileName;
        origData = Utils.toByteArray(is);
        this.fileSize = origData.length;
        ByteArrayInputStream bais = new ByteArrayInputStream(origData);
        BDecoder bdecoder = new BDecoder();
        List<BElement> bElements = bdecoder.decode(bais);
        BDictionary dict = (BDictionary)bElements.get(0);
        meta = new MetaFile(dict);
    }
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    //@SearchableId
    public Long getId() {
        return id;
    }

    @ManyToOne
    public User getOwner() {
        return owner;
    }

    /**
     * @return the meta
     */
    @OneToOne
    public MetaFile getMeta() {
        return meta;
    }

    /**
     * @param meta the meta to set
     */
    public void setMeta(MetaFile meta) {
        this.meta = meta;
    }

    /**
     * @return the origData
     */
    @Column(length = 2097152)
    @Lob()
    public byte[] getOrigData() {
        return origData;
    }

    /**
     * @param origData the origData to set
     */
    public void setOrigData(byte[] origData) {
        this.origData = origData;
    }

    public void setOwner(User owner) {
        this.owner = owner;
    }

    public void setId(Long id) {
        this.id = id;
    }
    /**
     * @return the fileName
     */
    public String getFileName() {
        return fileName;
    }

    /**
     * @param fileName the fileName to set
     */
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    /**
     * @return the fileSize
     */
    public int getFileSize() {
        return fileSize;
    }

    /**
     * @param fileSize the fileSize to set
     */
    public void setFileSize(int fileSize) {
        this.fileSize = fileSize;
    }

    @Transient
    public byte[] computeOrigDataMD5() throws NoSuchAlgorithmException {
        MessageDigest algorithm = MessageDigest.getInstance("MD5");
        algorithm.getDigestLength();
        return algorithm.digest(origData);
    }
}
